/**
 * 支付宝工具包
 * 请勿修改此处代码，因为插件更新后此处代码会被覆盖。
 * 作者：VK
 * 发布于：2021-07-06
 */
const crypto = require("crypto");

var alipay = {};

var ALIPAY_ALGORITHM_MAPPING = {
	RSA: 'RSA-SHA1',
	RSA2: 'RSA-SHA256'
};

/**
 * 签名
 * @param {String} method 方法名
 * @param {Object} params 参数
 * @param {Object} config 配置
 */
alipay.sign = function(method, originalParams, config) {
	let params = JSON.parse(JSON.stringify(originalParams));
	let signParams = Object.assign({
		method,
		app_id: config.appId,
		charset: config.charset || "utf-8",
		version: config.version || "1.0",
		sign_type: config.signType || "RSA2",
	}, params);
	if (config.appCertSn && config.alipayRootCertSn) {
		signParams = Object.assign({
			app_cert_sn: config.appCertSn,
			alipay_root_cert_sn: config.alipayRootCertSn,
		}, signParams);
	}
	const bizContent = params.bizContent || params.biz_content;
	if (bizContent) {
		signParams.biz_content = JSON.stringify(bizContent);
	}
	// 排序
	const decamelizeParams = alipay.sortObj(signParams);
	// 拼接url参数
	let signStr = alipay.objectToUrl(decamelizeParams);

	let keyType = config.keyType || 'PKCS8';
	const privateKeyType = keyType === 'PKCS8' ? 'PRIVATE KEY' : 'RSA PRIVATE KEY'
	let privateKey = alipay.formatKey(config.privateKey, privateKeyType);
	// 计算签名
	const sign = crypto.createSign(ALIPAY_ALGORITHM_MAPPING[signParams.sign_type]).update(signStr, 'utf8').sign(privateKey, 'base64');
	return Object.assign(decamelizeParams, { sign });
};
/**
 * 格式化请求 url（按规范把某些固定的参数放入 url）
 * @param {Object} params 参数
 * @param {String} url 请求地址
 */
alipay.formatUrl = function(params, url = "https://openapi.alipay.com/gateway.do") {
	let requestUrl = url;
	// 需要放在 url 中的参数列表
	const urlArgs = [
		'app_id', 'method', 'format', 'charset',
		'sign_type', 'sign', 'timestamp', 'version',
		'notify_url', 'return_url', 'auth_token', 'app_auth_token',
		'ws_service_url',
	];
	for (const key in params) {
		if (urlArgs.indexOf(key) > -1) {
			const val = encodeURIComponent(params[key]);
			requestUrl = `${requestUrl}${requestUrl.includes('?') ? '&' : '?'}${key}=${val}`;
			// 删除 postData 中对应的数据
			delete params[key];
		}
	}
	return { execParams: params, url: requestUrl };
};

/**
 * 对象属性排序
 * @param {Object} obj
 */
alipay.sortObj = function(obj) {
	let sortArry = new Array;
	let keysArr = Object.keys(obj).sort();
	let sortObj = {};
	for (let i in keysArr) {
		sortObj[keysArr[i]] = (obj[keysArr[i]]);
	}
	return sortObj;
};
/**
 * 对象转url参数
 * @param {Object} obj
 */
alipay.objectToUrl = function(obj) {
	let str = "";
	for (let key in obj) {
		if (obj[key]) {
			str += `&${key}=${obj[key]}`;
		}
	}
	if (str) str = str.substring(1);
	return str;
};
/**
 * 格式化证书key
 * @param {String} key 密钥串
 * @param {String} type 密钥类型
 */
alipay.formatKey = function(key, type) {
	return `-----BEGIN ${type}-----\n${key}\n-----END ${type}-----`
};

/**
 * alipay.fund.trans.uni.transfer 返回 alipay_fund_trans_uni_transfer_response
 */
alipay.getRequestRes = function(result, method) {
	let successKey = method.replace(new RegExp('\\.', 'g'), '_') + '_response';
	let errorKey = "error_response";
	return result[successKey] || result[errorKey];
};


module.exports = alipay;
